﻿#include "ui/helpers.h"
#include "ui/controls.h"
#include "context.h"
#include "texture.h"
#include "draw.h"

using namespace std;
using namespace anip;

void ui::FlowHelper::_BeginRow::paint()
{
	auto textTex = getTextTexture();
	if (textTex == nullptr) return;
	vec2 size = getTextSize();
	Draw::text(_absPos, size, *textTex, textColor);
}

void ui::FlowHelper::_BeginRow::flow(Flow& f)
{
	vec2 tsize = getTextSize();
	f.lineHeight = tsize.y + r::Flow_Text_hMargin * 2;
	setPosition({ 
		f.currentX,
		f.currentY + r::Flow_Text_hMargin });
	setSize({ 0, 0 });
	f.hasRowHeader = true;
	f.currentX = f.containerWidth * f.columnFactor + r::Flow_Separator;
}

void ui::FlowHelper::_EndRow::flow(Flow& f)
{
	f.hasRowHeader = false;
	f.newLine();
}

ui::Control* ui::FlowHelper::beginRow(Container& p, const wstring& text)
{
	auto c = new _BeginRow();
	p.addChild(*c);
	c->setText(text);
	return c;
}

ui::Control* ui::FlowHelper::endRow(Container& p)
{
	auto c = new _EndRow();
	p.addChild(*c);
	return c;
}

ui::Label* ui::FlowHelper::label(Container& p, const wstring& text)
{
	auto c = new Label(&p);
	c->layoutOptions.type = Control::LayoutOptions::Flow;
	c->setText(text);
	return c;
}

ui::Button* ui::FlowHelper::button(Container& p, const wstring& text)
{
	auto c = new Button(&p);
	c->layoutOptions.type = Control::LayoutOptions::Flow;
	c->setText(text);
	return c;
}

ui::Slider* ui::FlowHelper::slider(Container& p, float min, float max, float val)
{
	auto c = new Slider(&p);
	c->layoutOptions.type = Control::LayoutOptions::Flow;
	c->layoutOptions.stretchX = 1;
	c->setRange(min, max);
	c->setValue(val);
	return c;
}

ui::Joystick* ui::FlowHelper::joystick(Container& p)
{
	auto c = new Joystick(&p);
	c->layoutOptions.type = Control::LayoutOptions::Flow;
	return c;
}

ui::TextField* ui::FlowHelper::textField(Container& p, const wstring& text)
{
	auto c = new TextField(&p);
	c->layoutOptions.type = Control::LayoutOptions::Flow;
	c->layoutOptions.stretchX = 1;
	c->setText(text);
	return c;
}

ui::RadioBar* ui::FlowHelper::radioBar(Container& p, int n, const wstring* items)
{
	auto c = new RadioBar(&p);
	c->layoutOptions.type = Control::LayoutOptions::Flow;
	for (int i = 0; i < n; i++)
		c->addItem(items[i]);
	return c;
}

ui::FoldablePanel* ui::FlowHelper::foldablePanel(Container& p, const wstring& text)
{
	auto c = new FoldablePanel(&p);
	c->setText(text);
	c->layoutOptions.type = Control::LayoutOptions::Flow;
	c->layoutOptions.stretchX = 1;
	return c;
}

ui::Menu& ui::MenuHelper::globalMenu(invec2 pos)
{
	auto menu = new Menu((Container*)Control::topContainer(), pos);
	return *menu;
}

ui::MenuBar::Item& ui::MenuHelper::barButton(MenuBar& m, const wstring& text,
	const function<void(MenuBar::Item& self)>& onclick)
{
	auto item = new MenuBar::Item(m, text);
	item->onClick = onclick;
	return *item;
}

ui::MenuBar::Item& ui::MenuHelper::barDropdown(MenuBar& m, const wstring& text,
	const function<Menu* (MenuBar::Item& self)>& sub)
{
	auto item = new MenuBar::Item(m, text);
	item->getSubMenu = sub;
	return *item;
}

ui::MenuTextItem& ui::MenuHelper::button(Menu& m, const wstring& text,
	const function<void(MenuTextItem& self)>& onclick)
{
	auto item = new MenuTextItem(m, text);
	item->onClick = onclick;
	return *item;
}

ui::MenuTextItem& ui::MenuHelper::checkable(Menu& m, const wstring& text, bool checked,
	const function<void(MenuTextItem& self)>& onclick)
{
	auto item = new MenuTextItem(m, text,
		checked ? MenuTextItem::CheckState::Checked :
		MenuTextItem::CheckState::Unchecked);
	item->onClick = onclick;
	return *item;
}

ui::MenuTextItem& ui::MenuHelper::subMenu(Menu& m, const wstring& text,
	const function<Menu* (MenuTextItem& self)>& sub)
{
	auto item = new MenuTextItem(m, text);
	item->getSubMenu = sub;
	return *item;
}

ui::MenuSeparatorItem& ui::MenuHelper::separator(Menu& m)
{
	auto item = new MenuSeparatorItem(m);
	return *item;
}

ui::MenuLabelItem& ui::MenuHelper::text(Menu& m, const wstring& text)
{
	auto item = new MenuLabelItem(m, text);
	return *item;
}

ui::MenuLabelItem& ui::MenuHelper::groupHeader(Menu& m, const wstring& text)
{
	auto item = new MenuLabelItem(m, text);
	item->textColor = r::Menu_LineColor;
	return *item;
}

ui::MenuRadioBarItem& anip::ui::MenuHelper::radioBar(Menu& m, bool multi, bool none)
{
	auto item = new MenuRadioBarItem(m);
	item->allowMultipleSelect = multi;
	item->allowZeroSelect = none;
	return *item;
}

ui::MenuRadioBarItem& anip::ui::MenuHelper::buttonBar(Menu& m)
{
	auto item = new MenuRadioBarItem(m);
	item->allowSelect = false;
	return *item;
}

ui::MenuRadioBarSubItem& anip::ui::MenuHelper::radioItem(
	MenuRadioBarItem& bar, 
	const wstring& text, 
	const function<void(MenuRadioBarSubItem& self)>& onclick)
{
	auto& item = bar.addItem(text);
	item.onClick = onclick;
	return item;
}

void ui::NonIntrusiveDialog::show(Control& cont)
{
	auto menu = new ui::Menu((Container*)&cont);
	ui::MenuHelper::text(*menu, _text);
	auto& bar = ui::MenuHelper::buttonBar(*menu);
	for (auto& b : _btns)
	{
		auto click = b.click;
		ui::MenuHelper::radioItem(bar, b.text,
			[=, &bar](ui::MenuRadioBarSubItem& self)
			{
				click();
				bar.menu().markDelete();
			});
	}
	menu->setPosition(cont.toLocalPos(Context::mousePos()));
}